package ex1;

/**
 * Defines common interface for all kinds of cells.
 */
public interface ICell {
	
	/**
	* Initializes all neighbours of the cell.
	* 
	* @param tl top left cell
	* @param tr top middle cell
	* @param tr top right cell
	* @param l left cell
	* @param r right cell
	* @param bl bottom left cell
	* @param bm bottom middle cell
	* @param br bottom right cell
	*/
	void init (ICell tl, ICell tm, ICell tr, ICell l, ICell r, ICell bl, ICell bm, ICell br);
	
	/**
	 * Tries to get the cell to its next generation, according to the rules of the game. 
	 * No evolution will occure if one of the neighbours isn't ready, or the max generation has been reached.
	 * 
	 * @return true if evolution occured, false otherwise.
	 */
	boolean evolve ();
	
	/**
	 * Returns the state (dead/alive) of the cell in the supplied generation.
	 * 
	 * @param generation The desired generation.
	 * @return True if alive, false if dead.
	 * @throws NotReady If the cell doesn't have record of the supplied generation. (History is 2 latest states)
	 */
	boolean getState (int generation) throws NotReady;
	
	/**
	 * Should wake up the owning Thread of the cell (if needed for that kind of cell).
	 */
	void wakeOwner ();
	
	/**
	 * Checks if the cell has reached its maximal generation.
	 * 
	 * @return true if maximal generation has been reached, false otherwise.
	 */
	boolean done ();
	
	/**
	 * Checks whether or not all of the neighbours of the cell are ready.
	 * 
	 * @return true if the neighbours are ready, false otherwise.
	 */
	boolean canEvolve ();
}

class NotReady extends Exception {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
}